<?php
/**
 * | 节程 [ 节程赋能开发者，助力企业发展 ]
 * +----------------------------------------------------------------------
 *  | Copyright (c) 2020~2029 温州惊蛰网络科技有限公司 All rights reserved.
 * +----------------------------------------------------------------------
 *  | Licensed 节程并不是自由软件，未经许可不能去掉节程相关版权
 * +----------------------------------------------------------------------
 */


namespace app\command;

use think\console\Input;
use think\console\Output;
use think\Exception;
use think\facade\Db;

class OrderEnd extends BaseCommand
{
    protected function configure()
    {
        // 指令配置
        $this->setName('order_end')
            ->setDescription('订单完结');
    }

    protected function execute(Input $input, Output $output)
    {
        $this->setDb($input, $output);
    }

    protected function executeAction(Input $input, Output $output)
    {
        $config = Db::name('configuration')
            ->field('mall_id,configuration')
            ->where('type', 'tradeSetting')
            ->select()
            ->toArray();
        $template = Db::name('express_template')->field('id')->select();
        foreach ($config as $key => $value) {
            Db::startTrans();
            try {
                $js = json_decode($value['configuration'], true);
                if (empty($js['order_end_time'])) $js['order_end_time'] = -1;
                Db::name('order_commodity')
                    ->where('mall_id', $value['mall_id'])
                    ->where('status', 'in', [5,7])
                    ->where('after_status','<>',1)
                    ->where('receiving_time', '<', date('Y-m-d H:i:s', time() - ($js['order_end_time']) * 86400))
                    ->where('order_id','NOT IN',function($sql){
                        $sql->name('order')->field('id')->where('status',4);
                    })
                    ->update(['status' => 4, 'update_time' => date('Y-m-d H:i:s')]);
                $order = Db::query('select (CASE WHEN count(*)=SUM(`status` IN (4,9,11)) THEN `order_id` ELSE 0 END) AS `order_id` from `jiecheng_order_commodity` where order_id IN (SELECT `order_id` FROM `jiecheng_order_commodity` WHERE `status` = 4) and `order_id` IN (select `id` from `jiecheng_order` where `status` IN (5,8,9,11)) GROUP BY order_id');
                $order_id = array_unique(array_column($order, 'order_id'));
                $order = Db::name('order')
                    ->where('id', 'IN', $order_id)
                    ->where('status', 'NOT IN', [4, 12])
                    ->where('delete_time IS NULL')
                    ->select()
                    ->toArray();
                $order_id = array_column($order, 'id');
                foreach ($order as $k => $v) {
                    foreach ($template as $index => $item) {
                        $is_bool = file_exists(root_path('public/expressbill') . $item['id'] . '-' . $v['order_no'] . $v['id'] . '.log');
                        if ($is_bool)
                            unlink(root_path('public/expressbill') . $item['id'] . '-' . $v['order_no'] . $v['id'] . '.log');
                    }
                    //TODO 计算金额给商户
                    if ($v['settlement'] === 1) {
                        $settlement = Db::name("merchant_settlement")
                            ->where(['mall_id' => $v['mall_id'], 'merchant_id' => $v['merchant_id'], 'order_no' => $v['order_no']])
                            ->find();
                        if (!empty($settlement['account']))
                            Db::name('merchant_cash')
                                ->where(['mall_id' => $v['mall_id'], 'merchant_id' => $v['merchant_id']])
                                ->inc('total', (float)$settlement['account'])
                                ->inc('recharge', (float)$settlement['account'])
                                ->update();
                    }
                }
                Db::name('order')
                    ->where('id', 'IN', $order_id)
                    ->update(['status' => 4, 'settlement' => 2, 'update_time' => date('Y-m-d H:i:s')]);
                Db::commit();
            } catch (Exception $e) {
                Db::rollback();
                throw new Exception($e->getMessage(), 500);
            }
        }

        Db::startTrans();
        try {
            $orderIds = Db::name('order')
                ->where(['status' => 12, 'settlement' => 1, 'is_rebate' => 1])
                ->whereNull('delete_time')
                ->column('id');
            if (!empty($orderIds)) {
                $settlements = Db::table('jiecheng_merchant_settlement')->where(['id' => $orderIds])->select();
                if ($settlements) {
                    foreach ($settlements as $settlement) {
                        Db::name('merchant_cash')
                            ->where(['mall_id' => $settlement['mall_id'], 'merchant_id' => $settlement['merchant_id']])
                            ->inc('total', (float)bcadd((string)$settlement['account'], (string)$settlement['agent_cash']))
                            ->inc('recharge', (float)bcadd((string)$settlement['account'], (string)$settlement['agent_cash']))
                            ->update();
                        Db::name('order')->where(['id' => $settlement['id']])->update(['settlement' => 2]);
                    }
                }
            }

            Db::commit();
        } catch (Exception $e) {
            Db::rollback();
            throw new Exception($e->getMessage(), 500);
        }
    }
}